import Vuex from 'vuex'
import Vue from 'vue'
import {
  INCREMENT
} from './mutations-types'

// 1. 安装vuex
Vue.use(Vuex)


// 创建一个moduleA对象
const moduleA = {
  state: {
    name: "Mr.chen"
  },
  mutations: {
    updateName(state, payload) {
      state.name = payload
    }
  },
  actions: {
    // 此context非原context 可以理解为当前moduleA对象
    aUpdateName(context) {
      // context中可以访问到根的getters与state
      console.log(context)
      setTimeout(() => {
        context.commit('updateName', 'Mr.xiao')
      }, 1000)
    }
  },
  getters: {
    // 用法与store对象中使用一致
    fullname(state) {
      return state.name + " 返回"
    },

    // getters 当前getters对象
    fullname2(state, getters) {
      return getters.fullname + " 再次返回"
    },

    // rootState 原始store对象
    fullname3(state, getters, rootState) {
      return getters.fullname + rootState.counter
    }
  }
}


// 2. 创建Vuex对象: 单一状态数\数据源
// 好处：方便后期管理维护
const store = new Vuex.Store({
  // 保存共享状态 Devtools浏览器插件 记录行为
  // 修改状态步骤：Vue Components(Vue组件) --Dispatch(分发)--> Actions(行为，异步操作) --commit(提交)--> mutations(同步操作 ) 
  state: {
    counter: 1000,
    students: [
      {id: 110, name: "chen", age: 2},
      {id: 111, name: "xiao", age: 10},
      {id: 112, name: "fang", age: 20},
      {id: 113, name: "shan", age: 30},
    ],
    info: {
      // 这里所有的属性都会被加入到响应式系统中 前提：属性已经定义好了，否则无法存入到响应式系统中
      // Dep 观察者 观察是否存在变化，如果监听变化了，通知所有对应需要改变的地方进行改变
      name : 'kobe',
      age: 40,
      height: 1.98
    }
  },

  // 处理同步操作
  mutations: {
    // 方法自带state状态参数 可以把mutations中的函数看做两部分 提交时携带的参数被称为patload(载荷）
    // 1. 事件类型(increament) 2. 回调函数(state){}
    // [特殊函数定义方式]
    [INCREMENT](state) {
      state.counter++
    },
    decrement(state) {
      state.counter--
    },
    // 1. 普通提交风格 
    // incrementCount(state, count) {
    //   console.log(count)
    //   state.counter += count
    // },
    // 2. 特殊提交风格 对象
    incrementCount(state, payload) {
      console.log(payload)
      state.counter += payload.count
    },
    addStudent(state, student) {
      state.students.push(student)
    },
    updateInfo(state, payload) {
      // 无响应式：变量没有提前进行定义 无法存入到响应式系统中
      // state.info['address'] = "洛杉矶"

      // 响应式：使用Vue强行添加至响应式中
      // Vue.set(state.info, 'address', '洛杉矶')

      // 响应式：变量已经提前定义
      // state.info.name = payload.name

      // 无响应式：删除属性，属性确实删除却无法更新页面
      // delete state.info.name

      // 响应式：使用Vue删除
      // Vue.delete(state.info, 'name')

      // 在mutations中进行异步操作 可能会存在devtool工具跟踪不到的情况 官方强调不要在mutations中进行异步
      // 在mutations中的操作必须都是同步的 
      // setTimeout(() => {
      //   state.info.name = payload.name
      // }, 2000)

      // 配合异步
      state.info.name = payload
    },
  },

  // 异步操作处理
  actions: {
    // context 上下文 目前可以理解成store对象
    aUpdateInfo(context, payload) {
      // setTimeout(() => {
      //   console.log(payload.name)
      //   context.commit('updateInfo', payload.name)
      //   payload.success()
      // }, 2000)

      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log(payload)
          context.commit('updateInfo', payload)

          // 调用resolve
          resolve(payload)
        }, 1000)
      })

    }
  },

  // 类似计算属性：需要缓存多次调用的时候
  getters: {
    // 每次都要获取counter平方
    powerCounter(state) {
      return state.counter * state.counter
    },
    // 过滤大于20岁的学生
    more20stu(state) {
      // filter中获取一个个数组中的单个数据 组成一个新数组 条件为true时添加至新数组
      return state.students.filter(stu => stu.age > 20)
    },
    // 过滤大于20岁的学生
    more20stuLength(state, getters) {
      // filter中获取一个个数组中的单个数据 组成一个新数组 条件为true时添加至新数组
      return getters.more20stu.length
    },
    // 外部传入条件进行过滤 
    // 使用我们的moreAgeStu只是一个属性不是函数，为了达到接收外部参数的传递，内部闭包封装一个函数返回，并接收参数传递即可
    moreAgeStu(state) {
      // 箭头函数接收参数age 进行条件过滤 
      return age => { 
        return state.students.filter(stu => stu.age > age) 
      }
    }
  },


  modules: {
    a: moduleA
  }
})

// 3. 导出Vux对象
export default store 


